<template>
  <div class="container">
    <div class="sub-category">
      <!-- 面包屑 -->
      <SubBread />
      <!-- 筛选区 -->
      <SubFilter />
      <div class="goods-list">
        <!-- 结果 - 头部筛选 -->
        <SubSort></SubSort>
        <!-- 加载 -->
        <XtxInfiniteLoading
          v-model:loading="loading"
          :finished="finished"
          @loadMore="getGoodsFn"
        >
          <!-- 商品列表 -->
          <ul>
            <li v-for="item in goods.items" :key="item.id">
              <GoodsItem :goods="item" />
            </li>
          </ul>
        </XtxInfiniteLoading>
      </div>
    </div>
  </div>
</template>

<script>
import SubBread from './components/sub-bread'
import SubFilter from './components/sub-filter'
import { findSubCategoryFilterAPI, findGoodsAPI } from '@/api/category'
import { provide, reactive, ref, toRefs, watch } from 'vue'
import { useRoute } from 'vue-router'
import SubSort from './components/sub-sort.vue'
import GoodsItem from './components/goods-item.vue'

export default {
  name: 'SubCategory',
  components: { SubBread, SubFilter, SubSort, GoodsItem },
  setup () {
    const route = useRoute() // 路由

    /* 重置筛选数据 */
    const defaultParams = () => ({
      /**
       * sortField - 排序字段，取值范围：[publishTime,orderNum,price,evaluateNum]
       * sortMethod - 排序规则，asc为正序，desc为倒序，默认为desc
       * inventory - 是否有库存
       * onlyDiscount - 只显示特惠
       */
      sortField: null,
      sortMethod: null,
      inventory: false,
      onlyDiscount: false,
      // attrs: [{ groupName: null, propertyName: null }]
      attrs: []
    })

    /* 重置页码数据 */
    const defaultPage = () => ({
      page: 0, // 页码
      pageSize: 10 // 页容量
    })

    /* 获取商品 */
    const getGoodsFn = async () => {
      // 超出总数就停止请求
      const isFull =
        total.value !== 0 &&
        goods.value.items &&
        goods.value.items.length >= total.value
      if (isFull) return (onLoad.finished = true)

      pageParams.page++ // 页码++

      // console.log(pageParams.page)
      // 发送请求
      console.log('获取商品')
      const result = await findGoodsAPI({
        ...sortParams, // 筛选参数
        ...pageParams, // 分页参数
        categoryId: route.params.id // 必传id
      })

      if (total.value === 0) total.value = result.counts // 总数

      const hasData = goods.value.items && goods.value.items.length
      // 空数组
      if (!hasData) goods.value = result
      // 已有数据
      if (hasData) goods.value.items.push(...result.items)
    }

    /* proxy */
    const subCate = ref({}) // 分类数据
    const goods = ref({}) // 商品数据
    const total = ref(0) // 总条数
    const sortParams = reactive(defaultParams()) // 筛选条件
    const pageParams = reactive(defaultPage()) // 分页条件
    const onLoad = reactive({
      loading: false,
      finished: false
    }) // 加载更多数据

    /* 注入 */
    provide('sortParams', sortParams)
    provide('pageParams', pageParams)
    provide('subCate', subCate)

    /* 初始数据渲染 */
    watch(
      () => route.params.id,
      async id => {
        // 重置筛选条件
        /**
         * ! 坑点
         * ! sub.vue 的 setup() 执行顺序早于 xtx-infinite 的 useIntersectionObserver
         * ! 但被 await 请求异步化拖慢执行顺序，故放请求前
         */
        const obj = defaultParams()
        Object.keys(obj).map(key => (sortParams[key] = obj[key]))

        // 发送请求
        const isSub = route.path === `/category/sub/${id}`
        if (isSub) subCate.value = await findSubCategoryFilterAPI(id)
      },
      { immediate: true }
    )

    /* 监听筛选参数 */
    /**
     * ? 需求：切换筛选参数 后 重置页码和商品数据
     */
    watch(
      sortParams,
      async () => {
        // console.log('已重置筛选条件')
        // 重置页码数据
        const obj = defaultPage()
        Object.keys(obj).map(key => (pageParams[key] = obj[key]))
        onLoad.finished = false // 重置完成态
        if (goods.value.items) goods.value.items.length = 0 // 清空商品
        total.value = 0 // 重置总数
        getGoodsFn()
      },
      { deep: true }
    )

    /* 监听页码参数 */
    // watch(
    //   () => pageParams.page,
    //   () => getGoodsFn(),
    //   { immediate: true }
    // )

    /**
     * ! 鱼与熊掌不可兼得，分开两个对象！
    // 监听请求参数变化
    watch(
      sortParams,
      async () => {
        // 超出总数就停止
        const isFull =
          goods.value.items && goods.value.items.length >= total.value
        if (isFull) onLoad.finished = true

        // console.log(sortParams.page)
        // 发送请求
        const result = await findGoodsAPI({
          ...sortParams,
          ...pageParams,
          categoryId: route.params.id
        })
        total.value = result.counts // 更新总数(考虑到筛选)

        const hasData = goods.value.items && goods.value.items.length
        // 空数组
        if (!hasData) goods.value = result
        // 已有数据
        if (hasData) goods.value.items.push(...result.items)
      },
      { deep: true }
    ) */

    return { subCate, sortParams, goods, total, getGoodsFn, ...toRefs(onLoad) }
  }
}
</script>

<style scoped lang="less">
.goods-list {
  background: #fff;
  padding: 0 25px;
  margin-top: 25px;
  ul {
    display: flex;
    flex-wrap: wrap;
    padding: 0 5px;
    li {
      margin-right: 20px;
      margin-bottom: 20px;
      &:nth-child(5n) {
        margin-right: 0;
      }
    }
  }
}
</style>
